import { Test, TestingModule } from "@nestjs/testing";
import { AppModule } from "../src/app.module";
import { INestApplication } from "@nestjs/common";
import { setupApp } from "../src/setup";
import datasource from '../ormconfig'
import { DataSource } from "typeorm";
import { readFileSync } from "fs";
import { join } from "path";

export class AppFactory {
  connection: DataSource;
  constructor(
    private app: INestApplication
  ) {}

  get instance(){
    return this.app;
  }

  // 初始化App实例
  static async init(){
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    const app = moduleFixture.createNestApplication();
    setupApp(app);
    const port = 3000;
    await app.listen(port);
    await app.init();
    return new AppFactory(app);
  }
  // apptest: string;

  // 初始化db数据库
  async initDB(){
    if (!datasource.isInitialized){
      await datasource.initialize();
    }
    this.connection = datasource;
    // 将基础的字典数据写入数据库
    const queryRunner = this.connection.createQueryRunner();
    const sql = readFileSync(join(__dirname, '../src/migrations/init.sql'))
      .toString()
      .replace(/\r?\n|\r/g, '')
      ?.split(';') || [];
      // console.log('sql',sql);
    for (let i = 0; i < sql.length; i++) {
      var el = sql[i];
      if (el.trim() == '') continue;
      await queryRunner.query(sql[i]);
    }
  }
  // 清除数据库数据 -> 避免测试数据污染
  async cleanup(){
    const entities = this.connection.entityMetadatas;
    for (const entity of entities){
      const repository = this.connection.getRepository(entity.name);
      await repository.query(`DELETE FROM ${entity.tableName}`);
    }
  }
  // 断开与数据库的链接 -> 避免后续数据库连接过多而无法连接
  async destory(){
    await this.connection?.destroy();
  }
}
